import { Button, Space } from 'antd'
import cs from 'classnames'
import dayjs from 'dayjs'
import { debounce } from 'lodash'
import { useEffect, useRef, useState } from 'react'

import useLocale from '@/utils/useLocale'

import locale from './locale'
import styles from './style//index.module.less'
type File = { path: string; name: string }[]

function Camera({ onCamera, back }: { onCamera?: (file: File) => void; back: () => void }) {
  const t = useLocale(locale)
  const videoRef = useRef(null)
  const [videoDevices, setVideoDevices] = useState([])
  const [enable, setEnable] = useState<boolean>(false)

  const [deviceId, setDeviceId] = useState<any>()
  const mediaStream = useRef<any>() // 定义一个变量用于保存获取到的摄像头流
  const getUserMedia = () => {
    // 获取摄像头设备
    navigator.mediaDevices
      .enumerateDevices()
      .then(function (devices) {
        // 用于存储摄像头设备的数组
        const videoDevices = []

        devices.forEach(function (device) {
          // 过滤出摄像头设备
          if (device.kind === 'videoinput') {
            videoDevices.push(device)
          }
        })
        setVideoDevices(videoDevices)
        // 检查是否有可用的摄像头设备
        if (videoDevices.length > 0) {
          // 选择后置摄像头
          const backCamera = videoDevices[videoDevices.length - 1]
          // 如果找到前置摄像头，则使用该设备
          // 否则，使用第一个摄像头设备
          const selectedCamera = backCamera || videoDevices[0]
          getStream(selectedCamera)
        } else {
          console.log('No video devices found')
        }
      })
      .catch(function (err) {
        console.log(err)
      })
  }

  const getStream = (selectedCamera) => {
    const rect = contentRef.current.getBoundingClientRect()
    const w = rect.width || 1920
    const h = rect.height || 1080
    setDeviceId(selectedCamera)
    // 使用摄像头设备
    navigator.mediaDevices
      .getUserMedia({
        video: {
          deviceId: selectedCamera.deviceId,
          width: { ideal: w },
          height: { ideal: h },
          frameRate: { ideal: 30 }, // 设置帧率为30帧每秒
        },
      })
      .then(function (stream) {
        mediaStream.current = stream
        videoRef.current.srcObject = stream
        videoRef.current.play()
        setEnable(true)
        // const track = stream.getVideoTracks()[0]
        // const capabilities = track.getCapabilities()
        // console.log('Device capabilities for ', capabilities)
      })
      .catch(function (err) {
        console.log(err)
      })
  }

  const releaseUserMedia = async () => {
    if (mediaStream.current) {
      const tracks = mediaStream.current.getTracks()
      tracks &&
        tracks.forEach(async (track) => {
          await track.stop()
        })
      mediaStream.current = null
    }
  }

  useEffect(() => {
    setEnable(false)
    getUserMedia()
    const rect = contentRef.current.getBoundingClientRect()
    setCw(rect.width * 0.8)
    setCh(rect.height * 0.8)
    window.addEventListener('resize', updateScreenSize)
    return () => {
      releaseUserMedia()
      window.removeEventListener('resize', updateScreenSize)
    }
  }, [])

  const canvasRef = useRef(null)
  const [cw, setCw] = useState<number>(0)
  const [ch, setCh] = useState<number>(0)
  const contentRef = useRef(null)

  const updateScreenSize = debounce(async () => {
    if (contentRef) {
      const rect = contentRef.current.getBoundingClientRect()
      setCw(rect.width * 0.8)
      setCh(rect.height * 0.8)

      await releaseUserMedia()
      getUserMedia()
    }
  }, 200)

  const [isTake, setIsTake] = useState<boolean>(false)
  const take = () => {
    const context = canvasRef.current.getContext('2d')
    // 绘制视频截图，保持比例
    const scale = Math.min(
      canvasRef.current.width / videoRef.current.videoWidth,
      canvasRef.current.height / videoRef.current.videoHeight
    )
    const width = videoRef.current.videoWidth * scale
    const height = videoRef.current.videoHeight * scale
    const x = (canvasRef.current.width - width) / 2
    const y = (canvasRef.current.height - height) / 2
    context.drawImage(
      videoRef.current,
      0,
      0,
      videoRef.current.videoWidth,
      videoRef.current.videoHeight,
      x,
      y,
      width,
      height
    )
    setIsTake(true)
  }

  const clear = () => {
    setIsTake(false)
  }

  const submit = () => {
    releaseUserMedia()
    canvasRef.current.toBlob(
      async (blob) => {
        const arrayBuffer = await blob.arrayBuffer()
        const filename = dayjs().unix()
        const path = window.electron.ipcRenderer.addFile(arrayBuffer, `${filename}.png`)

        onCamera([path])
      },
      'image/jpeg',
      0.95
    )
  }

  const switchCamera = () => {
    releaseUserMedia()
    const index =
      videoDevices.findIndex(function (device) {
        return device.deviceId === deviceId.deviceId
      }) + 1
    const selectedCamera = videoDevices[index % videoDevices.length]
    getStream(selectedCamera)
  }

  return (
    <div className={styles['camera']}>
      <div className={styles['content']} ref={contentRef}>
        <video ref={videoRef} className={styles['video']}></video>

        <div className={cs(styles['canvas'], isTake ? 'flex' : 'hidden')}>
          <canvas
            key={cw}
            ref={canvasRef}
            width={cw}
            height={ch}
            // className={styles['canvas']}
          ></canvas>
        </div>

        <Space className={styles['action']} size={20}>
          {isTake ? (
            <>
              <Button
                type="primary"
                ghost
                shape="round"
                className={styles['button']}
                onClick={clear}
              >
                {t['clear']}
              </Button>
              <Button type="primary" shape="round" className={styles['button']} onClick={submit}>
                {t['submit']}
              </Button>
            </>
          ) : (
            <>
              <Button
                type="primary"
                ghost
                shape="round"
                className={styles['button']}
                onClick={() => back()}
              >
                {t['cancel']}
              </Button>
              <Button
                type="primary"
                ghost
                shape="round"
                className={styles['button']}
                onClick={switchCamera}
              >
                {t['switch']}
              </Button>
              <Button
                type="primary"
                shape="round"
                className={styles['button']}
                onClick={take}
                disabled={!enable}
              >
                {t['take']}
              </Button>
            </>
          )}
        </Space>
      </div>
    </div>
  )
}

export default Camera
